package com.rainman.noswagger;


import com.github.javaparser.ParseResult;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.TypeDeclaration;
import com.rainman.noswagger.info_bean.ClassInfoBean;
import com.rainman.noswagger.core.CoreConfig;
import com.rainman.noswagger.info_bean.MethodInfoBean;
import com.rainman.noswagger.util.FileUtils;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;

public class NoSwaggerCore {

    private final CoreConfig coreConfig;
    private final List<File> javaFileList;
    private final List<ClassInfoBean> classInfoBeanList;
    private final HashMap<String,ClassInfoBean> classInfoBeanHashMap;


    public NoSwaggerCore(){
        coreConfig=new CoreConfig();
        javaFileList=new ArrayList<>();
        classInfoBeanList=new ArrayList<>();
        classInfoBeanHashMap=new HashMap<>();
    }

    /**
     * 扫描文件，并执行
     * @throws Exception
     */
    public List<MethodInfoBean> start()  {
        //扫描文件
        FileUtils.scannerJavaFiles(new File(coreConfig.getCodePath()),javaFileList);

        for(File file:javaFileList){

            ParseResult<CompilationUnit> parse = null;
            try {
                parse = coreConfig.getJavaParser().parse(file);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                continue;
            }

            if(!parse.isSuccessful()){
                log("err file"+file+" err:"+parse.getProblems());
                //System.out.println("err"+parse.getProblems());
                continue;
            }
            Optional<CompilationUnit> result = parse.getResult();

            if(!result.isPresent()){
                log("err file CompilationUnit not found"+file);
                continue;
            }

            //可读取文件则初始化ClassInfoBean
            initClass(result.get(),file);

        }

        //必须后执行buildController。才能匹配到类中变量
        for(ClassInfoBean classInfoBean:classInfoBeanList){

            //处理方法与方法参数
            classInfoBean.buildController();
        }

        return getAllMethodInfoBeans();
    }

    /**
     * 初始化ClassInfoBean
     * 获取初始信息
     * 初始化变量，未处理方法与方法参数
     *
     * @param compilationUnit
     * @param file
     */
    private void initClass(CompilationUnit compilationUnit,File file) {


        Optional<TypeDeclaration<?>> primaryType = compilationUnit.getPrimaryType();

        if(!primaryType.isPresent()){
            log("err file PrimaryTypeDeclaration not found"+file);
            return;
        }

        ClassInfoBean classInfoBean =
                new ClassInfoBean (compilationUnit, primaryType.get(),this);
        classInfoBeanList.add(classInfoBean);

        classInfoBeanHashMap.put(classInfoBean.getPackageName()+"."+classInfoBean.getName(),classInfoBean);
    }




    /**
     * 根据全类名或者全类名尾字符匹配ClassInfoBean
     * 如果全类名匹配不到
     * 则匹配末尾支付
     *
     * 如存在a.b.CEntity
     * 传入a.b.CEntity与CEntity都可匹配获得
     *
     * @param typeClassName
     * @return
     */
    public ClassInfoBean getClassInfo(String typeClassName){

        ClassInfoBean classInfoBean = classInfoBeanHashMap.get(typeClassName);

        if(classInfoBean==null){
            for(ClassInfoBean classInfoBean1:classInfoBeanList){
                if((classInfoBean1.getPackageName()+"."+classInfoBean1.getName()).endsWith(typeClassName)){

                    return classInfoBean1;
                }
            }
        }

        return classInfoBean;
    }

    public List<MethodInfoBean> getAllMethodInfoBeans() {

        List<MethodInfoBean> re=new ArrayList<>();
        for(ClassInfoBean classInfoBean:classInfoBeanList){
            re.addAll(classInfoBean.getMethodInfoBeanList());
        }
        return re;
    }

    public void log(String msg){
        System.out.println(msg);
    }
    public CoreConfig getCoreConfig() {
        return coreConfig;
    }
}
